﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Sholo.Web.Security.State
{
    /// <summary>
    /// ITicketStore defines the core contract that a ticket manager must implement in 
    /// order to support the UserAuthenticationTicket and/or DeviceAuthenticationTicket features.
    /// </summary>
    /// <typeparam name="TKey">The type of the key that identifies the ticket</typeparam>
    /// <typeparam name="TTicket">The type of the ticket to store</typeparam>
    public interface ITicketStore<TKey, TTicket>
    {
        /// <summary>
        /// You retrieve EnhancedSecurity properties in the constructor or else you will cause 
        /// a StackOverflow.  EnhancedSecurity.Initialize() will call Initialize() on all 
        /// relevant controls when its initialization is complete.  In Initialize(), you can 
        /// retrieve properties from EnhancedSecurity.
        /// </summary>
        void Initialize();

        /// <summary>
        /// Removes expired entries from the ticket store
        /// </summary>
        void RemoveExpiredTickets();

        /// <summary>
        /// Retrieve a ticket from the ticket store 
        /// by it's ticket key
        /// </summary>
        /// <param name="ticketKey">The ticket key generated by the server</param>
        /// <returns>The ticket or null if no matching ticket is found</returns>
        /// <exception cref="ArgumentNullException">ticketKey is null</exception>
        /// <exception cref="ArgumentException">ticketKey is empty</exception>
        TTicket GetTicket(TKey ticketKey);

        /// <summary>
        /// Inserts a ticket to the ticket store with a corresponding 
        /// ticket expiration date.
        /// </summary>
        /// <param name="ticket">The ticket to insert</param>
        /// <param name="expiration">The date and time at which the ticket expires</param>
        /// <exception cref="ArgumentNullException">Ticket is null</exception>
        void InsertTicket(TTicket ticket, DateTime expiration);

        /// <summary>
        /// Updates the expiration date and time for an existing ticket.  If the ticket does
        /// not exist in the ticket store, just return (do not throw an exception).
        /// </summary>
        /// <param name="ticket">The ticket to insert</param>
        /// <param name="newExpiration">The new expiration date and time</param>
        /// <exception cref="ArgumentNullException">Ticket is null</exception>
        void UpdateTicketExpiration(TTicket ticket, DateTime newExpiration);

        /// <summary>
        /// Removes the ticket from the collection if it exists.  If the ticket does not
        /// exist in the ticket store, just return (do not throw an exception).
        /// </summary>
        /// <param name="ticketKey">The key of the ticket to remove from the ticket store</param>
        /// <exception cref="ArgumentNullException">ticketKey is null</exception>
        /// <exception cref="ArgumentException">ticketKey is empty</exception>
        void RevokeTicket(TKey ticketKey);

        /// <summary>
        /// Indicates whether or not the ticket store contains the supplied ticketKey
        /// </summary>
        /// <param name="ticketKey">The ticket to check for</param>
        /// <returns>True if the ticket is contained in the store</returns>
        /// <exception cref="ArgumentNullException">ticketKey is null</exception>
        /// <exception cref="ArgumentException">ticketKey is empty</exception>
        bool ContainsTicket(TKey ticketKey);

        /// <summary>
        /// Retrieves all tickets in the ticket store that have not already expired.
        /// </summary>
        /// <returns>An enumerable collection of tickets</returns>
        IEnumerable<TTicket> GetAllTickets();

        /// <summary>
        /// Retrieves all ticket keys in the ticket store that have not already
        /// expired.
        /// </summary>
        /// <returns>An enumerable collection of ticket keys</returns>
        IEnumerable<TKey> GetAllTicketKeys();

        /// <summary>
        /// Verify that the supplied ticket exists in the ticket store
        /// </summary>
        /// <param name="ticket">The ticket to verify</param>
        /// <returns>
        /// True if the ticket exists in the ticket store and the properties of that 
        /// ticket match the properties of the ticket in the ticket store.
        /// </returns>
        bool VerifyTicket(TTicket ticket);
    }
}
